package com.xishu.shard;

import com.alibaba.druid.pool.DruidDataSource;
import com.xishu.config.Constant;
import io.shardingjdbc.core.api.ShardingDataSourceFactory;
import io.shardingjdbc.core.api.config.ShardingRuleConfiguration;
import io.shardingjdbc.core.api.config.strategy.ComplexShardingStrategyConfiguration;
import io.shardingjdbc.core.api.config.strategy.StandardShardingStrategyConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 分片配置
 */
//@Configuration
public class ShardingConfig {

    //    @Bean
    public DataSource shardingCustomer() throws SQLException {

        // 第一步: 获取众多数据源
        Map<String, DataSource> dataSourceMap = getDatasourceMap();

        // 第二步: 获取总配置类，这里分库分表
        ShardingRuleConfiguration shardingRuleConfig = getShardingRuleConfiguration();

        // 第三步: 获取其余配置信息(如果需要的话)
        Properties properties = getProperties();

        // 第四步: 创建并返回sharding总数据源,注入容器
        return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig,
                new ConcurrentHashMap<>(16), properties);
    }


    /**
     * 获取其余配置信息
     *
     * @return 其余配置信息
     */
    private Properties getProperties() {
        Properties properties = new Properties();
        // 打印出分库路由后的sql
        properties.setProperty("sql.show", "true");
        return properties;
    }

    /**
     * 获取数据源Map
     *
     * @return 获取数据源Map
     */
    private Map<String, DataSource> getDatasourceMap() {
        // 真实数据源map
        Map<String, DataSource> dataSourceMap = new HashMap<>(4);

        DruidDataSource dataSourceDefault = new DruidDataSource();
        dataSourceDefault.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSourceDefault.setUrl(String.format("jdbc:mysql://localhost:3306/%s?characterEncoding=utf8&useSSL=false&serverTimezone=GMT", Constant.DATA_SOURCE_DOLA));
        dataSourceDefault.setUsername("root");
        dataSourceDefault.setPassword("123456");
        dataSourceMap.put(Constant.DATA_SOURCE_DOLA, dataSourceDefault);

        DruidDataSource dataSourceYounger = new DruidDataSource();
        dataSourceYounger.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSourceYounger.setUrl(String.format("jdbc:mysql://localhost:3306/%s?characterEncoding=utf8&useSSL=false&serverTimezone=GMT", Constant.DATA_SOURCE_STANDBY));
        dataSourceYounger.setUsername("root");
        dataSourceYounger.setPassword("123456");
        dataSourceMap.put(Constant.DATA_SOURCE_STANDBY, dataSourceYounger);


        DruidDataSource dataSourceOlder = new DruidDataSource();
        dataSourceOlder.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSourceOlder.setUrl(String.format("jdbc:mysql://localhost:3306/%s?characterEncoding=utf8&useSSL=false&serverTimezone=GMT", Constant.DATA_SOURCE_XISHU));
        dataSourceOlder.setUsername("root");
        dataSourceOlder.setPassword("123456");
        dataSourceMap.put(Constant.DATA_SOURCE_XISHU, dataSourceOlder);
        return dataSourceMap;
    }

    /**
     * 获取切片总配置类
     *
     * @return 总配置类
     */
    private ShardingRuleConfiguration getShardingRuleConfiguration() {

        // sharding总配置类
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();

        // 设置全局默认库
        shardingRuleConfig.setDefaultDataSourceName(Constant.DATA_SOURCE_DOLA);

        // 设置全局默认分库的策略(本人这里采用：精确分片算法实现的标准分片策略)
        // 如果某个表，没有指定分库策略的话，那么会默认使用这个策略;如果某个表制定了自己的策略，那么就会走自己的策略不走这个默认策略
        shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(
                new StandardShardingStrategyConfiguration("shopid", DatabaseSharding.class.getName()));

        // 设置全局默认分表的策略(这里采用：复合分片策略)
        // 如果某个表，没有指定分表策略的话，那么会默认使用这个策略;如果某个表制定了自己的策略，那么就会走自己的策略不走这个默认策略
        StandardShardingStrategyConfiguration standardShardingStrategyConfiguration = new StandardShardingStrategyConfiguration(
                "shopid", TableSharding.class.getName());
        shardingRuleConfig.setDefaultTableShardingStrategyConfig(standardShardingStrategyConfiguration);
        return shardingRuleConfig;
    }


}
